#include "stdafx.h"
#include "CFactory.h"

int g_cServerLocks = 0;

CFactory::~CFactory()
{
}

ULONG CFactory::AddRef()
{
	RETAILMSG(TRUE, (TEXT("Factory Reference is now %d\r\n"), m_cRef + 1));
	return InterlockedIncrement(&m_cRef);
}

CFactory::CFactory()
{
	m_cRef = 1;
}

STDMETHODIMP CFactory::CreateInstance(LPUNKNOWN pUnknownOuter, REFIID iid, LPVOID *ppv)
{
	CSMSTasker *pClient = NULL;
	HRESULT hr;

	// No aggregation
	if (pUnknownOuter)
	{
		hr = CLASS_E_NOAGGREGATION;
		goto Error;

	}

	// You heard 'em, create a component
	pClient = new CSMSTasker();
	if (!pClient)
	{
		hr = E_OUTOFMEMORY;
		goto Error;
	}

	// Get the requested interface
	hr = pClient->QueryInterface(iid, ppv);

Error:
	// Release the unknown pointer
	if (pClient) 
	{
		pClient->Release();
	}

	return hr;
}

STDMETHODIMP CFactory::LockServer(BOOL bLock)
{
	if (bLock)
	{
		g_cServerLocks++;
	}
	else
	{
		g_cServerLocks--;
	}

	return S_OK;
}

STDMETHODIMP CFactory::QueryInterface(const IID& iid, LPVOID *ppv)
{
	HRESULT hr = E_NOINTERFACE;

	if (!ppv)
	{
		return E_INVALIDARG;
	}

	if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
	{
		*ppv = (LPVOID) this;
	}
	else
	{
		*ppv = NULL;
	}

	if (*ppv) 
	{
		((LPUNKNOWN) *ppv)->AddRef();
		hr = S_OK;
	}

	return hr;
}

ULONG CFactory::Release()
{
	InterlockedDecrement(&m_cRef);
	RETAILMSG(TRUE, (TEXT("Factory Reference is now %d\r\n"), m_cRef));

	int nLocal = m_cRef;

	if (!m_cRef) 
	{
		RETAILMSG(TRUE, (TEXT("CFactory Deleted!\r\n")));
		delete this; 
	}

	return nLocal; 
}